package com.storm.classes.pool
{
	import flash.utils.Dictionary;
	
	import mx.core.ClassFactory;

	public class Pool {
		public function Pool(itemClass:Class, poolSize:uint = 8, dynamic:Boolean = true) {
			this._factory = new ClassFactory(itemClass);
			this._poolSize = poolSize;
			this.clear();
			if (dynamic) return;
			this.createPool();
		}
		
		private var _factory:ClassFactory;
		public function get factory():ClassFactory {
			return this._factory;
		}
		
		private var _poolSize:uint;
		public function get poolSize():uint {
			return this._poolSize;
		}
		
		private var _indexDictionary:Dictionary;
		private var _items:Array;
		public function get items():Array {
			return this._items;
		}
		
		private var _freeItems:Array;
		public function get freeItems():Array {
			return this._freeItems;
		}
		
		protected function createPool():void {
			for (var i:int = 0; i < this._poolSize; i++) {
				this.newItem();
			}
		}
		
		protected function newItem():* {
			var item:* = this._factory.newInstance();
			this._indexDictionary[item] = this._items.push(item);
			this._freeItems.push(item);
			return item;
		}
		
		protected function tempItem():* {
			return this._factory.newInstance();
		}
		
		protected function isTemp(item:*):Boolean {
			return this._indexDictionary[item] === null;
		}
		
		public function get freeItem():* {
			if (this._freeItems.length) {
				return this._freeItems.pop();
			} else {
				if (this._items.length < this._poolSize) {
					return this.newItem();
				} else {
					return this.tempItem();
				}
			}
		}
		public function set freeItem(value:*):void {
			if (isTemp(value)) return;
			this._freeItems.push(value);
		}
		
		public function clear():void {
			for each (var item:* in this._items) {
				this._indexDictionary[item] = null;
			}
			this._indexDictionary = new Dictionary();
			this._items = [];
			this._freeItems = [];
		}
	}
}